﻿using UnityEngine;
using System.Collections;
using UnityEditor;
using System;

namespace Hont.HyperWigglePackage.Editor
{
    public class MotionBuilder_Arc : BaseWigglePlugins
    {
        PRPair[] mCacheData;
        float mArcValue;
        AnimationCurve mCurve;
        Camera mCamera;

        Vector3 mCameraCachePosition;
        Quaternion mCameraCacheRotation;

        bool mIsLocked;


        public override void Execute(HyperWiggleEditorCore core)
        {
            base.Execute(core);

            mCamera = mCore.View.PreviewRenderUtility.camera;

            mCameraCachePosition = mCamera.transform.position;
            mCameraCacheRotation = mCamera.transform.rotation;

            mCore.IsStopCameraControl = true;

            mCurve = new AnimationCurve(new Keyframe(0, 0), new Keyframe(0.5f, 1), new Keyframe(1, 0));
        }

        protected override void OnExit()
        {
            mCore.IsStopCameraControl = false;
        }

        protected override void OnGUI()
        {
            mCurve = EditorGUILayout.CurveField("Curve: ", mCurve);
            mArcValue = EditorGUILayout.Slider("Arc Value: ", mArcValue, -180f, 180f);

            GUILayout.BeginHorizontal();
            if (GUILayout.Button("Cancel"))
            {
                mArcValue = 0;
                mCamera.transform.position = mCameraCachePosition;
                mCamera.transform.rotation = mCameraCacheRotation;
                mCacheData.CopyTo(mCore.FrameData, 0);

                mCore.UpdatePreview();
                mCore.UpdateTimeline();
                mIsLocked = false;
                mCore.IsStopCameraControl = true;
            }

            if (GUILayout.Button("Apply"))
            {
                mCacheData = new PRPair[mCore.FrameData.Length];
                mCore.FrameData.CopyTo(mCacheData, 0);

                var lastPos = mCameraCachePosition;
                var lastQuat = mCameraCacheRotation;

                for (int i = 0; i < mCore.FrameData.Length; i++)
                {
                    var current = i / (float)mCore.EndFrame;
                    var lerp = mCurve.Evaluate(current);
                    var arc = mArcValue * lerp;

                    var currentQuat = Quaternion.AngleAxis(arc, Vector3.up);
                    var dir = mCameraCachePosition - Vector3.zero;
                    dir = currentQuat * dir;
                    var currentPosition = Vector3.zero + dir;

                    var posOffset = currentPosition - lastPos;
                    var rotOffset = currentQuat.eulerAngles - lastQuat.eulerAngles;

                    if (rotOffset.x > 180) rotOffset.x -= 360;
                    if (rotOffset.x < -180) rotOffset.x += 360;

                    if (rotOffset.y > 180) rotOffset.y -= 360;
                    if (rotOffset.y < -180) rotOffset.y += 360;

                    if (rotOffset.z > 180) rotOffset.z -= 360;
                    if (rotOffset.z < -180) rotOffset.z += 360;

                    mCore.FrameData[i].RelativePosition = posOffset;
                    mCore.FrameData[i].RelativeRotation = rotOffset;

                    lastQuat = currentQuat;
                    lastPos = currentPosition;
                }

                HyperWiggleUtil.StableOffset(mCore.FrameData);

                mCore.UpdatePreview();
                mCore.UpdateTimeline();
                mIsLocked = true;
                mCore.IsStopCameraControl = false;
            }

            GUILayout.EndHorizontal();

            if (!mIsLocked)
            {
                var quat = Quaternion.AngleAxis(mArcValue, Vector3.up);
                var dir = mCameraCachePosition - Vector3.zero;
                dir = quat * dir;

                mCamera.transform.position = Vector3.zero + dir;
                mCamera.transform.forward = -dir;
            }
        }
    }
}